package com.tech.distribute_lock.zk;

import com.tech.distribute_lock.DistributeLockStategy;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author litianlin
 * @date 2023/12/8 14:44
 * @description:
 */
@Slf4j
@Component
public class CuratorDistributeLockStategy implements DistributeLockStategy {
    private static final String LOCK_ROOT_PATH = "/curator/locks";
    /**lockKey-lockPath*/
    private static final ThreadLocal<ConcurrentHashMap<String, InterProcessMutex>> lockKeyLockMapTl = ThreadLocal.withInitial(ConcurrentHashMap::new);

    @Resource
    private CuratorFramework client;

    @Override
    public boolean tryLock(String lockKey, int expireTime) {
        InterProcessMutex mutex = lockKeyLockMapTl.get().get(lockKey);
        if(mutex==null){
            //创建分布式锁, 锁空间的根节点路径为/curator/lock
            mutex = new InterProcessMutex(client, getPath(LOCK_ROOT_PATH, lockKey));
        }
        return doLock(lockKey, mutex);
    }

    private boolean doLock(String lockKey, InterProcessMutex mutex) {
        try {
            mutex.acquire();
            lockKeyLockMapTl.get().putIfAbsent(lockKey, mutex);
            return true;
        } catch (Exception e) {
            log.error("", e);
        }

        return false;
    }

    private String getPath(String... paths) {
        return Arrays.stream(paths).collect(Collectors.joining("/"));
    }

    @Override
    public boolean unLock(String lockKey) {
        InterProcessMutex mutex = lockKeyLockMapTl.get().get(lockKey);
        if(mutex!=null){
            try {
                mutex.release();
                return true;
            } catch (Exception e) {
                log.error("", e);
            }
        }
        return false;
    }
}
